#include <cstdio>
#include <iostream>
#include <errno.h>
#include <string>
#include <mutex>

#include "datetime.h"
#include "logger.h"
#include "global.h"
#include "funcutil.h"
#include "readconf.h"

#ifndef NS_WB
#define NS_WB
#define NS_WB_BEGIN namespace wb {
#define NS_WB_END }
#endif
NS_WB_BEGIN //begin namespace wb

/**
 * @brief 修改数组为std::string，消除isoc++警告
 */
static const std::string lvlstr[LogLevel::MAXLEVEL] = {
    " [TRACE] ", " [DEBUG] ", " [INFO ] ",
    " [WARN ] ", " [ERROR] ", " [FATAL] "
};

Logger::Logger(SourceFile file, int line, LogLevel lvl)
    : filename_(file)
    , lineno_(line)
    , level_(lvl)
{
    oss_ << date_.toString() << wb::lvlstr[lvl]; //Date类的toString方法生成标准日期格式字符串
}

/**
 * @brief Destroy the Logger:: Logger object
 * 析构时调用cerr标准错误输出，后续可以改造，刷新到文件中
 */
Logger::~Logger()
{
    oss_ << " - " << filename_.data_ << ':' << lineno_ << std::endl;
    //输出到文件应该写到这里，内核会安排缓冲区的先后顺序，不需要上锁

    if (1)
    { //假设这里是一个判断，是否需要输出到屏幕
        std::unique_lock<std::mutex> ulock(logmtx_); //在输出到屏幕之前才上锁
        std::cerr << oss_.str() << std::endl;
    }
}

/**
 * @brief 返回当前日志级别
 * @return LogLevel
 */
LogLevel Logger::logLevel()
{
    return gs_level;
}

/**
 * @brief 设置当前的日志级别
 * @param  lvl 新的日志级别
 */
void Logger::setLogLevel(LogLevel lvl)
{
    gs_level = lvl;
}

LogLevel Logger::gs_level = LogLevel::TRACE;
std::mutex Logger::logmtx_{}; //静态成员初始化

NS_WB_END //end of namespace wb
